Zach的博客

Interaction Transition

Interaction Transition

为了自定义交互式的过渡动画,UIViewControllerTransitioningDelegate对象必须实现对应的协议方法,interactionControllerForPresentation(_:)interactionControllerForDismissal(_:)。交互控制根据用户的手势输入来更新自定义的过渡动画,
而自定的过度动画是实现了UIViewControllerAnimatedTransitioning协议的对象,关于该协议这里就不再说明了。

Apple提供了一个交互式控制器的具体实现UIPercentDrivenInteractiveTransition,在大多数情况下,我们的交互式控制器只要继承它,然后加入自己的手势交互就好了。

在我们的手势交互逻辑中,根据用户的输入,我们利用以下几个方法来实时更新动画:

1
2
3
4
5
func updateInteractiveTransition(_ percentComplete: CGFloat)

func cancelInteractiveTransition()

func finishInteractiveTransition()

一个简单的例子如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import UIKit

class SwipeInteractionController: UIPercentDrivenInteractiveTransition {
var interactionInProgress : Bool = false
private var shouldCompleteTransition : Bool = false
private weak var viewController : UIViewController!

func wireToViewController(viewController : UIViewController!) {
self.viewController = viewController
prepareGestureRecognizerInView(viewController.view)
}


func handleGesture(gestureRecognizer : UIScreenEdgePanGestureRecognizer) {
let translation = gestureRecognizer.translationInView(gestureRecognizer.view!.superview)
var progress = translation.x / 200.0
progress = CGFloat(fminf(fmaxf(Float(progress), 0.0), 1.0))

switch gestureRecognizer.state {
case .Began:
interactionInProgress = true
viewController.dismissViewControllerAnimated(true, completion: nil)
case .Changed:
shouldCompleteTransition = progress > 0.5
updateInteractiveTransition(progress)
case .Cancelled:
shouldCompleteTransition = false
interactionInProgress = false
cancelInteractiveTransition()
case .Ended:
interactionInProgress = false

if shouldCompleteTransition {
finishInteractiveTransition()
} else {
cancelInteractiveTransition()
}

default:
print("Unsupported")
}

}
// MARK: private
private func prepareGestureRecognizerInView(view : UIView) {
let edgeRecognizer = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(handleGesture))
edgeRecognizer.edges = UIRectEdge.Left
view.addGestureRecognizer(edgeRecognizer)
}
}

在定义了这个Animator之后,只要在另外一个对象(实现了UIViewControllerTransitioningDelegate协议)的interactionControllerForDismissal(_:)返回这个类的实例即可。

1
2
3
func interactionControllerForDismissal(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return swipeAnimator.interactionInProgress ? swipeAnimator : nil
}